
var jsdom = require('jsdom');
var http = require('http');
var fs = require('fs');

var app = {};


// callback = function (err, links)
app.fetchLinks = function (page_url, callback) {
  // Define general variables
  var _links = [];

  // Fetch the links
  jsdom.env(
    page_url,
    ['http://code.jquery.com/jquery.js'],
    function (errors, window) {
      // Fetch the photo link dom element array
      var elements = window.$('.pt_list_nb a');

      // Put the elements to general variable
      for (var i=0; i<elements.length; ++i) {
        _links.push(elements[i].attributes.href.value);
      }

      // Run the callback function
      callback(undefined, _links);
    }
  );
}


// callback = function (err, file_path)
app.fetchFile = function (file_url, save_path, callback) {
  http.get(file_url, function(res) {
    // Define general variables
    var chunks = [];
    var file = undefined;

    // Receive data from remote
    res.on('data', function (chunk) {
      chunks.push(chunk);
    });

    // Save the file
    res.on('end', function () {
      // Concat the buffers
      file = Buffer.concat(chunks);

      // Save the file
      fs.writeFile(save_path, file, function () {
        callback(undefined, save_path);
      });
    })
  }).on('error', function (err) {
    callback(err, undefined);
  });
}


// Next page handler
// callback = function (links)
app.nextPage = function (callback) {
  if (app.first_page <= app.current_page && app.current_page <= app.last_page) {
    app.fetchLinks(app.album_url + '/page' + app.current_page, function (err, fetchedLinks) {
      for (var i=0; i<fetchedLinks.length; ++i) {
        app.links.push(fetchedLinks[i]);
      }
      console.log(
        '[ ' + 'PAGE' + app.current_page + ' ]',
        'count=' + fetchedLinks.length,
        'total=' + app.links.length
      );
      app.current_page++;
      app.nextPage(callback);
    });
  } else {
    callback(app.links);
  }
}


// Next link handler
// callback = function ()
app.nextLink = function (callback) {
  // Check the last link index
  if (!app.last_link) {
    app.last_link = app.links.length - 1;
  }

  // Check the range of the link index
  if ( app.first_link <= app.current_link && app.current_link <= app.last_link &&
       0 <= app.current_link && app.current_link < app.links.length ) {
    // Construct the save path
    var save_path = app.save_dir + '/' + app.current_link + app.save_postfix;

    // Fetch the file from remote and save
    app.fetchFile(
      app.links[app.current_link],
      save_path,
      function (err, file_path) {
        // Detect error
        if (err) {
          console.log(
            '[ ERROR ]',
            'link=' + app.current_link,
            'url=' + app.links[app.current_link],
            'error=' + '"' + err.message + '"'
          );
          return;
        }

        // Inform success with the file path
        console.log(
          '[ ' + 'LINK' + app.current_link + ' ]',
          'url=' + app.links[app.current_link],
          'path=' + save_path
        );

        // Handle the next link
        app.current_link++;
        app.nextLink(callback);
      }
    );
  } else {
    // Run the callback function
    callback();
  }
}


// Application entry
app.run = function () {
  // Define general variables
  app.links = [];

  // Read the configurations file
  var configs = JSON.parse(fs.readFileSync(__dirname + '/configs.json'));

  // Configurations for next page handler
  app.album_url     = configs.next_page.album_url;
  app.first_page    = configs.next_page.first_page;
  app.last_page     = configs.next_page.last_page;
  app.current_page  = configs.next_page.current_page;

  // Configurations for next link handler
  app.save_dir     = configs.next_link.save_dir;
  app.save_postfix = configs.next_link.save_postfix;
  app.first_link   = configs.next_link.first_link;
  app.last_link    = configs.next_link.last_link;
  app.current_link = configs.next_link.current_link;
  
  
  // Check the save path
  if (!( fs.existsSync(app.save_dir) )) {
    console.log(
      '[ ERROR ]',
      'error=' + '"The save_dir does not exist."',
      'save_dir=' + app.save_dir
    );
    return;
  }

  // Discover all the links
  app.nextPage(function (links) {
    // Fetch all files
    app.nextLink(function () {
      console.log('finished ..');
    })
  });
}


// Run the application
app.run();


